package com.yyy.service;

import com.yyy.entity.Passenger;
import com.yyy.entity.Pnr;
import com.yyy.repository.PassengerRepository;
import org.hibernate.query.criteria.internal.CriteriaBuilderImpl;
import org.hibernate.query.criteria.internal.predicate.CompoundPredicate;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by admin on 2018/8/7.
 */
@Service
public class PassengerService extends AbstractBaseService<Passenger, Integer, PassengerRepository>  {
    public List<Passenger> findByNameLikeAndCardNum(String name, String cardNum) {
        return repository.findByNameLikeAndCardNum(name, cardNum);
    }

    public Page<Passenger> findBySpecification(final Passenger passenger) {
        return repository.findAll(createSpecification(passenger), PageRequest.of(0, 10));
    }

    private Specification<Passenger> createSpecification(final Passenger passenger) {
        return (Specification<Passenger>) (root, query, builder) -> {
            final List<Predicate> predicates = new ArrayList<>();
            if (!StringUtils.isEmpty(passenger.getType())) {
                predicates.add(builder.equal(root.get("type"), passenger.getType()));
            }
            if (passenger.getPnr() != null && !StringUtils.isEmpty(passenger.getPnr().getIssueOfficeCode())) {
                final Join<Pnr, Passenger> joinE = root.join("pnr", JoinType.LEFT);
                predicates.add(builder.equal(joinE.get("issueOfficeCode"), passenger.getPnr().getIssueOfficeCode()));
            }
            final CompoundPredicate cp = new CompoundPredicate((CriteriaBuilderImpl) builder,
                    Predicate.BooleanOperator.AND);
            cp.getExpressions().clear();
            cp.getExpressions().addAll(predicates);
            query.where(cp);
            return cp;
        };
    }
}
